package demo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 环境检查树构建器类
 * 负责构建环境检查的树形结构，并根据日志更新节点状态
 */
public class EnvironmentCheckTreeBuilder {

    // 节点映射表，用于快速查找节点
    private static final Map<String, TreeNode> nodeMap = new HashMap<>();

    /**
     * 构建环境检查的树形结构
     * @return 根节点
     */
    public static TreeNode buildTree() {
        // 创建根节点
        TreeNode root = new TreeNode("root", "根节点", null);

        // 第一层：阶段
        TreeNode stage1 = new TreeNode("stage1", "阶段1", "root");
        TreeNode stage2 = new TreeNode("stage2", "阶段2", "root");
        TreeNode stage3 = new TreeNode("stage3", "阶段3", "root");

        // 第二层：校验分类
        TreeNode category1 = new TreeNode("cat1", "校验分类1", "stage1");
        TreeNode category2 = new TreeNode("cat2", "校验分类2", "stage1");
        TreeNode category3 = new TreeNode("cat3", "校验分类3", "stage2");
        TreeNode category4 = new TreeNode("cat4", "校验分类4", "stage3");

        // 第三层：校验对象
        TreeNode obj1 = new TreeNode("obj1", "校验对象1", "cat1");
        TreeNode obj2 = new TreeNode("obj2", "校验对象2", "cat1");
        TreeNode obj3 = new TreeNode("obj3", "校验对象3", "cat2");
        TreeNode obj4 = new TreeNode("obj4", "校验对象4", "cat2");
        TreeNode obj5 = new TreeNode("obj5", "校验对象5", "cat2");
        TreeNode obj6 = new TreeNode("obj6", "校验对象6", "cat3");
        TreeNode obj7 = new TreeNode("obj7", "校验对象7", "cat4");
        TreeNode obj8 = new TreeNode("obj8", "校验对象8", "cat4");

        // 构建父子关系
        root.children.add(stage1);
        root.children.add(stage2);
        root.children.add(stage3);

        stage1.children.add(category1);
        stage1.children.add(category2);
        stage2.children.add(category3);
        stage3.children.add(category4);

        category1.children.add(obj1);
        category1.children.add(obj2);
        category2.children.add(obj3);
        category2.children.add(obj4);
        category2.children.add(obj5);
        category3.children.add(obj6);
        category4.children.add(obj7);
        category4.children.add(obj8);

        // 存入 map 方便后续查找
        nodeMap.clear();
        nodeMap.put("root", root);
        nodeMap.put("stage1", stage1);
        nodeMap.put("stage2", stage2);
        nodeMap.put("stage3", stage3);
        nodeMap.put("cat1", category1);
        nodeMap.put("cat2", category2);
        nodeMap.put("cat3", category3);
        nodeMap.put("cat4", category4);
        nodeMap.put("obj1", obj1);
        nodeMap.put("obj2", obj2);
        nodeMap.put("obj3", obj3);
        nodeMap.put("obj4", obj4);
        nodeMap.put("obj5", obj5);
        nodeMap.put("obj6", obj6);
        nodeMap.put("obj7", obj7);
        nodeMap.put("obj8", obj8);

        return root;
    }

    /**
     * 根据日志更新节点状态和使能
     * @param logs 日志列表
     */
    public static void updateNodeStatusAndEnable(List<LogEntry> logs) {
        // 更新所有叶子节点（校验对象）
        for (TreeNode node : nodeMap.values()) {
            if (node.children.isEmpty()) { // 是校验对象
                updateLeafNode(node, logs);
            }
        }

        // 自底向上更新父节点
        updateParentNodes();
    }

    /**
     * 更新叶子节点（校验对象）的状态和使能
     * @param node 叶子节点
     * @param logs 日志列表
     */
    private static void updateLeafNode(TreeNode node, List<LogEntry> logs) {
        String nodeId = node.id;

        // 获取该节点需要的 enable 日志 ID
        Map<String, String> enableMap = Config.ENABLE_LOG_ID_MAP.get(nodeId);
        if (enableMap != null && enableMap.containsKey("enable")) {
            String enableLogId = enableMap.get("enable");
            LogEntry enableLog = logs.stream()
                    .filter(l -> l.logId.equals(enableLogId) && l.type.equals("enable"))
                    .findFirst()
                    .orElse(null);
            if (enableLog != null) {
                node.enabled = Boolean.parseBoolean(enableLog.value);
            }
        }

        // 获取该节点需要的状态日志 ID
        Map<String, String> statusMap = Config.STATUS_LOG_ID_MAP.get(nodeId);
        if (statusMap != null && statusMap.containsKey("status")) {
            String statusLogId = statusMap.get("status");
            LogEntry statusLog = logs.stream()
                    .filter(l -> l.logId.equals(statusLogId) && l.type.equals("status"))
                    .findFirst()
                    .orElse(null);
            if (statusLog != null) {
                node.status = statusLog.value;
            }
        }
    }

    /**
     * 自底向上更新父节点状态
     * 先更新"校验分类"节点，再更新"阶段"节点
     */
    private static void updateParentNodes() {
        // 从叶子节点开始，逐层向上更新父节点

        // 先更新所有"校验分类"节点
        for (TreeNode cat : nodeMap.values()) {
            if (cat.parentId != null && (cat.parentId.equals("stage1") || cat.parentId.equals("stage2") || cat.parentId.equals("stage3"))) {
                updateCategoryNode(cat);
            }
        }

        // 再更新"阶段"节点
        for (TreeNode stage : nodeMap.values()) {
            if (stage.parentId != null && stage.parentId.equals("root")) {
                updateStageNode(stage);
            }
        }
    }

    /**
     * 更新分类节点状态
     * @param category 分类节点
     */
    private static void updateCategoryNode(TreeNode category) {
        List<TreeNode> children = category.children;
        boolean anyEnabled = children.stream().anyMatch(n -> n.enabled);
        category.enabled = anyEnabled;

        // 状态判断
        boolean allSuccess = children.stream().allMatch(n -> "成功".equals(n.status));
        boolean anyFailed = children.stream().anyMatch(n -> "失败".equals(n.status));
        boolean anyInitializing = children.stream().anyMatch(n -> "初始化".equals(n.status));

        if (anyFailed) {
            category.status = "失败";
        } else if (allSuccess) {
            category.status = "成功";
        } else if (anyInitializing) {
            category.status = "初始化";
        }
    }

    /**
     * 更新阶段节点状态
     * @param stage 阶段节点
     */
    private static void updateStageNode(TreeNode stage) {
        List<TreeNode> children = stage.children;
        boolean anyInitializing = children.stream().anyMatch(n -> "初始化".equals(n.status));
        boolean allSuccess = children.stream().allMatch(n -> "成功".equals(n.status));
        boolean anyFailed = children.stream().anyMatch(n -> "失败".equals(n.status));

        if (anyFailed) {
            stage.status = "失败";
        } else if (allSuccess) {
            stage.status = "成功";
        } else if (anyInitializing) {
            stage.status = "初始化";
        }
    }
}